tShapeContainer globalShapeContainer = null;
int screenSize[] = {1294,800};
tClueOverlay globalClueOverlay = null;
boolean clueIsActive = false;
tPalette globalPalette = null;
int globalGridSize = 1;
PFont menuFont = null;
tButtonContainer globalButtonContainer = null;
tScoreScreen globalScoreScreen = null;
boolean debug = true;

boolean mouseDown[] = new boolean[3];
boolean mouseJustPressed[] = new boolean[3];
boolean mouseJustReleased[] = new boolean[3];
int frameOnWhichMouseWasLastPressed[] = new int[3];
int frameOnWhichMouseWasJustPressed[] = new int[3];
int frameOnWhichMouseWasJustReleased[] = new int[3];
int frameOnWhichMouseWasLastReleased[] = new int[3];
boolean keyDown[] = new boolean[256];
boolean keyJustPressed[] = new boolean[256];
boolean keyJustReleased[] = new boolean[256];
int frameOnWhichKeyWasLastPressed[] = new int[256];
int frameOnWhichKeyWasJustPressed[] = new int[256];
int frameOnWhichKeyWasJustReleased[] = new int[256];
int frameOnWhichKeyWasLastReleased[] = new int[256];

images img;
menu mainMenu;

// the level the user is on, for each difficulty, set in levelSetup()
int userLevel[] = {1,1,1};
PImage levelOutline = null;
int levelOutlinePos[] = {screenSize[0]/2 - 970/2, screenSize[1]/2 - 600/2};

SolarSystem userSystem;
SolarSystem compSystem;

//0 : into; 1 : menu; 2 : game; 3 : 
int gameState = 0;
//0 : easy; 1 : medium; 2 : hard
int difficulty = 0;

void setup()
{
  img = new images();
  mainMenu = new menu();
  
  userSystem = new SolarSystem(difficulty);
  
  size(screenSize[0],screenSize[1],P3D);
  background(0);
  globalShapeContainer = new tShapeContainer();
  globalShapeContainer.initStandardShapes();
  globalClueOverlay = new tClueOverlay();
  globalPalette = new tPalette();
  menuFont = loadFont("data/SakkalMajallaBold-30.vlw");
  buttonSetupCredits();
  levelsSetup();
  scoreSetup();
  globalScoreScreen = new tScoreScreen();
  elementsSetup();
  clueSetup();
}

void draw()
{
  background(0);
  updateInput();
  
  switch(gameState)
  {
    case 0:
      img.drawIntro();
      break;
    case 1:
      globalButtonContainer.update(getMousePos());
      mainMenu.drawMenu();
      globalButtonContainer.doDraw();
      break;
    case 2:
      updateGame();
      drawBackground();
      drawGame();
      break;
    case 3:
      drawUserSystem();
      globalScoreScreen.update();
  }
}

void drawBackground()
{ 
  switch(difficulty)
  {
  case 0:
    image(img.easybg,0,0);
    break;
  case 1:
    image(img.medbg,0,0);
    break;
  case 2:
    image(img.hardbg,0,0);
    break;
  }
}

void drawGame()
{
  image(levelOutline,levelOutlinePos[0],levelOutlinePos[1]);
  fill(0,0,0,0);
  stroke(255);
  rect(levelOutlinePos[0],levelOutlinePos[1],970,600);
  globalPalette.doDraw();
  globalShapeContainer.doDraw();
  globalButtonContainer.doDraw();
  globalClueOverlay.doDraw();
}
void drawUserSystem()
{
  globalScoreScreen.doDraw();
}
void updateGame()
{
  int[] mousePos = getMousePos();
  globalPalette.update(mousePos);
  globalShapeContainer.update(mousePos);
  globalButtonContainer.update(mousePos);
  globalClueOverlay.update(mousePos);
  if (keyJustPressed['c'])
  {
    saveScreenCapture();
  }
}

void setGameState(int newGameState)
{
  switch(newGameState)
  {
    case 0:
      break;
    case 1:
      buttonSetupCredits();
      break;
    case 2:
      buttonSetup();
      break;
    case 3:
      break;
  }
  
  gameState = newGameState;
}

String coordsToString(int[][] coords)
{
  if (coords == null)
  {
    return "null";
  }
  
  String retval = "[";
  for (int i = 0; i < coords.length; i++)
  {
    retval += "[";
    for (int j = 0; j < coords[i].length; j++)
    {
      retval += coords[i][j];
      if (j < coords[i].length-1)
      {
        retval += ",";
      }
    }
    retval += "]";
    if (i < coords.length-1)
    {
      retval += ",";
    }
  }
  retval += "]";
  
  return retval;
}

/**
 * copies the coordinates from a to b
 * returns false if the coords are different lengths, true otherwise
 **/
boolean copyCoords(int[][] coordsA,int[][] coordsB)
{
  if (coordsA == null || coordsB == null ||
      (coordsA.length != coordsB.length))
  {
    return false;
  }
  
  for (int i = 0; i < coordsA.length; i++)
  {
    coordsB[i][0] = coordsA[i][0];
    coordsB[i][1] = coordsA[i][1];
  }
  
  return true;
}

void saveScreenCapture()
{
  PImage sandbox = ripSandbox(false);
  PImage outline = sandbox;
  String baseName = "";
  
  if (debug)
  {
    outline = convertToBW(sandbox);
    String difficulty_name = "";
    switch(difficulty)
    {
      case 0:
        difficulty_name = "easy";
        break;
      case 1:
        difficulty_name = "med";
        break;
      case 2:
        difficulty_name = "hard";
        break;
    }
    baseName = "levels/" + difficulty_name;
  }
  else
  {
    baseName += "screenshots/" + "ScreenCap";
  }
  
  int nextImagei = 1;
  while(loadImage(baseName + nextImagei + ".png") != null)
  {
    println(loadImage(baseName + nextImagei + ".png"));
    nextImagei++;
  }
  
  outline.save(baseName + nextImagei + ".png");
}
